﻿// Spun AJAX Framework
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Formality.Logic;
using System.Xml.Linq;
using System.Reflection;
using System.IO;
using Formality.FormalSystem;

namespace Formality.Levels
{
    public class LevelEnumerator
    {
        public LevelEnumerator(string Name)
        {
            this.Name = Name;
        }

        public IEnumerable<Sentence> Sentences
        {
            get
            {
                if (SentenceList == null)
                    SentenceList = LevelParser.ToList();

                return SentenceList;
            }
        }

        private IEnumerable<Sentence> LevelParser
        {
            get
            {
                var Name = typeof(LevelEnumerator).Namespace + '.' + this.Name;

                using (var Stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Name))
                using (var Reader = new StreamReader(Stream))
                {
                    var Doc = XDocument.Load(Reader);
                    var LevelContents = (from Level in Doc.Descendants("level")
                                         from Sent in Level.Descendants("s")
                                         select new
                                         {
                                             Level = (string)Level.Attribute("id"),
                                             Id = (string)Sent.Attribute("id"),
                                             Name = (string)Sent.Attribute("name"),
                                             Sentence = TryParse(Sent.Value)
                                         });


                    var SentenceQuery = from s in LevelContents
                                        select new
                                        {
                                            Id = "*" + s.Level + (s.Id == null ? "" : "." + s.Id) + ".",
                                            DisplayId = s.Name,
                                            Sentence = s.Sentence
                                        };

                    foreach (var s in SentenceQuery)
                    {
                        s.Sentence.DisplayId = s.DisplayId != null ? s.DisplayId : s.Id;
                        s.Sentence.Id = s.Id;

                        yield return s.Sentence;
                    }
                }
            }
        }

        private Sentence TryParse(string Input)
        {
            try
            {
                return Sentence.Parse(Input);
            }
            catch (Exception e)
            {
                throw new Exception("Could not parse " + Input, e);
            }
        }

        private string Name;
        private IEnumerable<Sentence> SentenceList;
    }
}
